local ArmourExcel = require("excel.Armour")
local ArmourBaseConfig = ArmourExcel.armour
local ArmourFeedConfig = ArmourExcel.feed
local ArmourHandler = require("armour.HandlerL")
local ObjHuman = require("core.ObjHuman")
local ArmourDefine = require("armour.Define")
local RoleAttr = require("role.RoleAttr")
local Util = require("common.Util")

function armourValid(armourID)
    local nArmourBaseConfig = ArmourBaseConfig[armourID]
    local nArmourLvUpConfig = getLvUpConfig(armourID)
    if not nArmourBaseConfig or not nArmourLvUpConfig or not isActive(armourID) then
        return false
    end
    return nArmourBaseConfig 
end

function isShow(id)
    if ArmourBaseConfig[id] and ArmourBaseConfig[id].show == 0 then
        return true
    end
    return false
end

function isActive(id)
    if ArmourBaseConfig[id] and ArmourBaseConfig[id].active == 0 then
        return true
    end
    return false
end

function getLvUpConfig(id)
    if ArmourBaseConfig[id] then
        local nArmourLvUpConfig = ArmourBaseConfig[id].conf
        if ArmourExcel[nArmourLvUpConfig] then
            return ArmourExcel[nArmourLvUpConfig]
        end
    end
    return nil 
end

function armourLvUp(human, id, lv, armourDBData)
    local nArmourDBData = armourDBData or getArmourDBData(armourID, human)
    if nArmourDBData then
        nArmourDBData.lv = nArmourDBData.lv + lv
        updateArmour(human, id)
        ObjHuman.doCalc(human)
        send2ClientAllAttrUpdate(human)
        return true
    end
    return false
end

function armourActive(human, id)
    -- 这里是根据数据库长度进行限制的，要增加战甲，则需要再roleffi里面增加armourlist的数组长度再操作
    if human.db.armourlistLen >= 32 then
        return false
    end

    local nArmourDBData = human.db.armourlist[human.db.armourlistLen]
    if nArmourDBData then
        nArmourDBData.armourid = id
        nArmourDBData.lv = 1
        nArmourDBData.state = ArmourDefine.ARMOUR_STATETYPE_UNHOLD 
        human.db.armourlistLen = human.db.armourlistLen + 1
        updateArmour(human, id)
        ObjHuman.doCalc(human)
        send2ClientAllAttrUpdate(human)
        return true
    end

    return false
end

function armourStarUp(human, id, star, armourDBData)
    local nArmourDBData = armourDBData or getArmourDBData(armourID, human)
    if nArmourDBData then
        nArmourDBData.star = nArmourDBData.star + star
        updateArmour(human, id)
        ObjHuman.doCalc(human)
        send2ClientAllAttrUpdate(human)
        return true
    end
    return false
end

function updateArmour(human, id)
    ArmourHandler.CG_ARMOUR_QUERY(human, {id = id})
end

function getArmourDBData(id, human)
    for i = 0, human.db.armourlistLen - 1 do
        if human.db.armourlist[i].armourid == id then
            return human.db.armourlist[i]
        end
    end
    return nil
end

local ALLATT_UPDATE = {}
function calcAllAttr(human)
    ALLATT_UPDATE = {}
    for i = 0, human.db.armourlistLen - 1 do
        local nArmourID = human.db.armourlist[i].armourid
        if armourValid(nArmourID) then
            local nArmourLv = human.db.armourlist[i].lv
            local nArmourBaseConfig = ArmourBaseConfig[nArmourID]
            local nArmourLvUpConfig = getLvUpConfig(nArmourID)
            if nArmourLvUpConfig then
                if nArmourLvUpConfig[nArmourLv] then
                    local nLvData = nArmourLvUpConfig[nArmourLv]
                    if nLvData then
                        for nIndex, nAttrData in ipairs(nLvData.addAttr) do
                            ALLATT_UPDATE[nAttrData[1]] = (ALLATT_UPDATE[nAttrData[1]] or 0) + nAttrData[2]
                        end
                    end
                end

                local nArmourStar = human.db.armourlist[i].star
                local nStarAttrConfig = ArmourBaseConfig[nArmourID].starattrdata[nArmourStar]
                if nStarAttrConfig then
                    for nIndex, nAttrData in ipairs(nStarAttrConfig) do
                        ALLATT_UPDATE[nAttrData[1]] = (ALLATT_UPDATE[nAttrData[1]] or 0) + nAttrData[2]
                    end
                end

                --加培养属性
                local len = #nArmourBaseConfig.feedAttr
                if len > 8 then len = 8 end
                for j = 1, len do
                    local k = nArmourBaseConfig.feedAttr[j][1]
                    ALLATT_UPDATE[k] = ALLATT_UPDATE[k] or 0
                    ALLATT_UPDATE[k] = ALLATT_UPDATE[k] + human.db.armourlist[i].feedAttr[j-1]
                    if ALLATT_UPDATE[k] == 0 then
                        ALLATT_UPDATE[k] = nil
                    end
                end

            end
        end
    end
    return ALLATT_UPDATE
end

function armourFeed(human, id, armourbaseconfig, armourDBData, addattr)
    local nAddAttrLen = #armourbaseconfig.feedAttr
    for i = 1, nAddAttrLen do
        if addattr[armourbaseconfig.feedAttr[i][1]] then
            armourDBData.feedAttr[i-1] = armourDBData.feedAttr[i-1] + addattr[armourbaseconfig.feedAttr[i][1]]
            if armourDBData.feedAttr[i-1] > armourbaseconfig.feedAttr[i][2] then
                armourDBData.feedAttr[i-1] = armourbaseconfig.feedAttr[i][2]
            end
        end
    end
    return true
end

--计算培养值
function randFeed(human,  id, armourbaseconfig, data, attrlen)
    if isFeedFull(human, id, armourbaseconfig, data) then
        return
    end

    local process = 0
    for i = 1, attrlen do
        process = process + data.feedAttr[i-1]/armourbaseconfig.feedAttr[i][2]
    end
    process = math.floor(process / attrlen * 100)

    local feed
    for i = 1, #ArmourFeedConfig do
        if process < ArmourFeedConfig[i].progress then
            feed = ArmourFeedConfig[i]
            break
        end
    end
    if not feed then
        return
    end

    local attrCnt
    local sum = 0
    for i = 1, attrlen do
        sum = sum + (feed.weight[i] or 0)
    end
    local randVal = math.random(1, sum)
    sum = 0
    for i = 1, attrlen do
        sum = sum + (feed.weight[i] or 0)
        if sum >= randVal then
            attrCnt = i
            break
        end
    end
    local ret = {}
    local start = math.random(1,  attrlen)
    local realCnt = 0
    for i = 1, attrlen do
        if ret[armourbaseconfig.feedAttr[start][1]] == nil and data.feedAttr[start-1] < armourbaseconfig.feedAttr[start][2] and (attrCnt >= attrlen or math.random(1, 10000)%2  == 1) then
            ret[armourbaseconfig.feedAttr[start][1]] = math.random(armourbaseconfig.feedAttr[start][3], armourbaseconfig.feedAttr[start][4])
            realCnt = realCnt + 1
        end
        start = start + 1
        if start > attrlen then
            start = 1
        end
        if realCnt == attrCnt then
            break
        end
    end
    if realCnt < attrCnt then --再算一篇，无随机属性的
        for i = 1, attrlen do
            if ret[armourbaseconfig.feedAttr[start][1]] == nil and data.feedAttr[start-1] < armourbaseconfig.feedAttr[start][2] then
                ret[armourbaseconfig.feedAttr[start][1]] = math.random(armourbaseconfig.feedAttr[start][3], armourbaseconfig.feedAttr[start][4])
                realCnt = realCnt + 1
            end
            start = start + 1
            if start > attrlen then
                start = 1
            end
            if realCnt == attrCnt then
                break
            end
        end
    end

    if realCnt > 0 then
        return ret
    end
end

-- 是否培养已满
function isFeedFull(human, id, armourbaseconfig, data)
    if not data then
        return true
    end
    local attrlen = #armourbaseconfig.feedAttr
    if attrlen > 8 then
        attrlen = 8
    end
    for i = 1, attrlen do
        if data.feedAttr[i-1] < armourbaseconfig.feedAttr[i][2] then
            return
        end
    end
    return true
end

function send2ClientAllAttrUpdate(human)
    ArmourHandler.sendArmourAllAttr(human, ALLATT_UPDATE)
end

function doCalc(human)
    calcAllAttr(human)
    if ALLATT_UPDATE then
        for k, v in pairs(ALLATT_UPDATE) do
            human.attr[k] = human.attr[k] + v
        end
    end
end

function setArmourShowInfo(info, id)
    if armourValid(id) then
        local nArmourLvUpConfig = getLvUpConfig(id)
        if nArmourLvUpConfig and nArmourLvUpConfig[1] then
            info.id = id
            info.effect = 0 
            info.attr[0] = #nArmourLvUpConfig[1].addAttr
            for k, v in ipairs(nArmourLvUpConfig[1].addAttr) do
                info.attr[k].key = v[1]
                info.attr[k].value = v[2]
            end
            info.type = 5
            local nInitAttr = {}
            for k, v in ipairs(nArmourLvUpConfig[1].addAttr) do
                nInitAttr[v[1]] = v[2]
            end
            info.power = RoleAttr.calHumanPower(nInitAttr)
        end
    end
end
